package dup.login.demo.controller;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import dup.login.demo.domain.*;
import dup.login.demo.queue.RabbitProducer;
import dup.login.demo.queue.RetryProducer;
import dup.login.demo.service.FileService;
import dup.login.demo.util.WordTemplate;
import dup.login.demo.service.impl.UserServiceImpl;
import dup.login.demo.util.ExcelUtil;
import dup.login.demo.util.ResultUtil;
import dup.login.demo.util.WordUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.format.annotation.NumberFormat;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.websocket.server.PathParam;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

//@Controller
@RestController
@RequestMapping(value = "/test")
public class TestController {
    //@RequestMapping(value = "/sayhello", method = RequestMethod.GET)
    //@GetMapping(value = {"/sayhello", "hi"})
    @PostMapping("/sayhello")
    //@ResponseBody
    public String sayHello(@RequestParam(value = "name", required = true, defaultValue = "") String name) {
        return "Hello Spring Boot!" + name;
    }

    @PostMapping("/getuser")
    public User getUser(User user) {
        return user;
    }

    @PostMapping("/test1")
    public String getTest1(String var1, String var2, Integer var3) {
        return var1 + var2 + var3;
    }

    @PostMapping("/test2")
    public Object getTest2(@RequestParam("var1") String var) {
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("var", var);
        return params;
    }

    @PostMapping("/test3")
    public ArrayList<String> getTest3(@RequestParam("var1") ArrayList var) {
        return var;
    }

    @PostMapping("/test4")
    public User getTest4(@RequestBody User user) {
        return user;
    }

    @PostMapping("/test5/{id}")
    public User getTest5(@PathParam("id") User user) {
        return user;
    }

    @PostMapping("/test6")
    public Map<String, Object> getTest6(DateFormat date, @NumberFormat(pattern = "#,###.##") Double number) {
        Map<String, Object> data = new HashMap<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateFormat = simpleDateFormat.format(date.getDate());
        data.put("date", dateFormat);
        data.put("number", number);

        return data;
    }

    @PostMapping("/test7")
    public User getTest7(User user) {
        return user;
    }

    @PostMapping("/test8")
    public Result getTest8(@Valid Test test, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(10000, bindingResult.getFieldError().getDefaultMessage());
        }
        return ResultUtil.success(test);
    }

    @PostMapping("/test9")
    public Result getTest9(@Valid Test2 test2, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(10000, bindingResult.getFieldError().getDefaultMessage());
        }
        return ResultUtil.success(test2);
    }

    @PostMapping("/test10")
    public Object getTest10(@Valid Test2 test2, BindingResult bindingResult) {
        System.out.println("我是控制器开始！");
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(10000, bindingResult.getFieldError().getDefaultMessage());
        }
        System.out.println("我是控制器结束！");
        return "我是控制器结果！";
    }

    @Autowired
    UserServiceImpl userServiceImpl;

    @PostMapping("/test11")
    public void getTest11() {
        userServiceImpl.getUserMsg();
        System.out.println("我是AOP测试控制层~");
    }


    @Resource
    private DefaultRedisScript<Boolean> redisScript;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserServiceImpl getUserServiceImpl;

    @PostMapping("/test12")
    public Object lua() {
        List<String> keys = Arrays.asList("testLua", "hello lua");
        Boolean execute = stringRedisTemplate.execute(redisScript, keys, "100");
        redisTemplate.opsForValue().set("test2", getUserServiceImpl.getUserList());

//        return ResponseEntity.ok(execute);
        return redisTemplate.opsForValue().get("test2");
    }

    @Autowired
    private RabbitProducer rabbitProducer;

    @PostMapping("/test13")
    public Object queueTest() {
        rabbitProducer.stringSend();
        return "ok";
    }

    @Autowired
    private RetryProducer retryProducer;

    @PostMapping("/test14")
    public Object queueTest2() {
        retryProducer.send1();
        return "ok";
    }

    @PostMapping("/test15")
    public Object Test15(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum) {
//        return new PageEntity<>(userServiceImpl.getUserList());
        PageHelper.startPage(pageNum, 1);
        List<User> userList = getUserServiceImpl.getUserList();
        PageInfo<User> pageInfo = new PageInfo<User>(userList);
        return pageInfo;
    }

    @Autowired
    private FileService fileService;

    @PostMapping("/test16")
    public Object Test16(@RequestParam("file") MultipartFile file) {
        return fileService.uploadFile(file, "test");
    }

    @PostMapping("/test17")
    public Object Test17(HttpServletRequest request) {
        List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
        return fileService.uploadMultipartFile(files, "test");
    }

    @GetMapping("/test18")
    public void Test18(String fileDir, HttpServletResponse response) {
        fileService.downloadFile(fileDir, response);
    }

    @GetMapping("/test19")
    public void Test19(HttpServletResponse response) {
        List<User> list = userServiceImpl.getUserList();
        ExcelData data = new ExcelData();
        data.setTitle("这是测试1111");
        data.setName("这是测试");
        List<String> titles = new ArrayList();
        titles.add("用户ID");
        titles.add("用户名");
        titles.add("邮箱");
        data.setTitles(titles);

        List<List<Object>> rows = new ArrayList();
        for (int i = 0, length = list.size(); i < length; i++) {
            User userInfo = list.get(i);
            List<Object> row = new ArrayList();
            row.add(userInfo.getId());
            row.add(userInfo.getName());
            row.add(userInfo.getEmail());
            rows.add(row);
        }
        data.setRows(rows);
        try {
//            rowIndex = ExcelUtil.generateExcel(data, "E://test//test.xls");
            ExcelUtil.exportExcel(response, "test", data);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @PostMapping("/test20")
    public Object Test20(MultipartFile file) {
        try {
            long t1 = System.currentTimeMillis();
            List<Test3> list = ExcelUtil.importExcel(file, Test3.class, "aaa", 2);
            long t2 = System.currentTimeMillis();
            System.out.println(String.format("read over! cost:%sms", (t2 - t1)));
            list.forEach(
                    b -> System.out.println(JSON.toJSONString(b))
            );
            return list;
        } catch (Exception e) {
            throw new RuntimeException("文件上传失败！");
        }
    }

    @PostMapping("/test21")
    public List Test21(MultipartFile file) {
        try {
            return WordUtil.readWord(file);
        } catch (Exception e) {
            throw new RuntimeException("文件上传失败！");
        }
    }

    @PostMapping("/test22")
    public String Test22() {
        Map<String, Object> wordDataMap = new HashMap<String, Object>();// 存储报表全部数据
        Map<String, Object> parametersMap = new HashMap<String, Object>();// 存储报表中不循环的数据


        List<Map<String, Object>> table1 = new ArrayList<Map<String, Object>>();
        Map<String, Object> map1 = new HashMap<>();
        map1.put("name", "张三");
        map1.put("age", "23");
        map1.put("email", "12121@qq.com");

        Map<String, Object> map2 = new HashMap<>();
        map2.put("name", "李四");
        map2.put("age", "45");
        map2.put("email", "45445@qq.com");

        Map<String, Object> map3 = new HashMap<>();
        map3.put("name", "Tom");
        map3.put("age", "34");
        map3.put("email", "6767@qq.com");

        table1.add(map1);
        table1.add(map2);
        table1.add(map3);


        List<Map<String, Object>> table2 = new ArrayList<Map<String, Object>>();
        Map<String, Object> map4 = new HashMap<>();
        map4.put("name", "tom");
        map4.put("number", "sd1234");
        map4.put("address", "上海");

        Map<String, Object> map5 = new HashMap<>();
        map5.put("name", "seven");
        map5.put("number", "sd15678");
        map5.put("address", "北京");

        Map<String, Object> map6 = new HashMap<>();
        map6.put("name", "lisa");
        map6.put("number", "sd9078");
        map6.put("address", "广州");

        table2.add(map4);
        table2.add(map5);
        table2.add(map6);


        parametersMap.put("userName", "JUVENILESS");
        parametersMap.put("time", "2018-03-24");
        parametersMap.put("sum", "3");


        wordDataMap.put("table1", table1);
        wordDataMap.put("table2", table2);
        wordDataMap.put("parametersMap", parametersMap);
        try {
            return WordUtil.writeWord(wordDataMap, "tp");
        } catch (Exception e) {
            return "error";
        }

//        File file = new File("E:\\test\\tp.docx");//改成你本地文件所在目录
//
//        try {// 读取word模板
//            FileInputStream fileInputStream = new FileInputStream(file);
//            WordTemplate template = new WordTemplate(fileInputStream);
//            // 替换数据
//            template.replaceDocument(wordDataMap);
//            //生成文件
//            File outputFile = new File("E:\\test\\tp1.docx");//改成你本地文件所在目录
//            FileOutputStream fos = new FileOutputStream(outputFile);
//            template.getDocument().write(fos);
//            fos.close();
//            fileInputStream.close();
//        } catch (Exception e) {
//            throw new RuntimeException("word文档写入失败！");
//        }
    }
}
